package org.example.admin.manage.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.example.admin.manage.form.SysAdminForm;
import org.example.admin.manage.service.SysAdminService;
import org.example.commons.config.MiniProgramInspectorsProperties;
import org.example.commons.constant.Constants;
import org.example.commons.constant.HttpStatusConstant;
import org.example.commons.controller.BaseController;
import org.example.commons.entity.SysAdmin;
import org.example.commons.entity.SysUser;
import org.example.commons.entity.SysUserRole;
import org.example.commons.service.ISysUserRoleService;
import org.example.commons.utils.SortUtils;
import org.example.commons.utils.WeiXinUtils;
import org.example.commons.vo.ResultVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * author 陈伯瑞
 * date 2020/5/26 0026 11:06
 * version 1.0
 **/
@Secured("ROLE_SUPER_ADMIN")
@RestController
@RequestMapping("/api/admin")
public class SysAdminController extends BaseController {

    @Autowired
    SysAdminService sysAdminService;

    @Autowired
    private MiniProgramInspectorsProperties inspectorsProperties;

    @Autowired
    private ISysUserRoleService userRoleService;

    /**
     * 导出excel
     * @param response
     * @throws IOException
     */
    @GetMapping("/export/excel")
    public void exportExcel(@RequestParam(name = "ids", required = false)  Long[] ids,
                            HttpServletResponse response) throws IOException {
        List<SysAdmin> data = null;
        if (ids==null || ids.length==0){
            data = sysAdminService.queryAll();
        }else {
            data = sysAdminService.findByAdminIdIn(ids);
        }
        super.exportExcel(response,data,SysAdmin.class,"管理员数据表");
    }

    /**
     *
     */
    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @GetMapping("/{id}")
    public ResultVO findOne(@PathVariable("id") Long id) {
        return ResultVO.success(sysAdminService.queryById(id));
    }

    @GetMapping("/openid")
    public ResultVO findByOpenid(@RequestParam("openid") String openid) {
        return ResultVO.success(sysAdminService.findByOpenid(openid));
    }

    /**
     * 用于注册登录
     *
     * @param phone 管理员电话
     * @return ResultVO
     */
    @GetMapping("/phone")
    public ResultVO findByPhone(@RequestParam("phone") String phone) {
        return ResultVO.success(sysAdminService.findByPhone(phone));
    }

    /**
     * 判断该电话是否改换给管理员（管理员修改电话）
     *  true 可以被修改
     * @param phone 电话
     * @return ResultVO
     */
    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @GetMapping("/phone/judge")
    public ResultVO judgePhone(@RequestParam("phone") String phone,@RequestParam("adminId") Long adminId) {
        SysAdmin sysAdmin = sysAdminService.findByPhone(phone);
        if (Objects.isNull(sysAdmin))        //该电话尚未被人注册
            return ResultVO.success(true);
        else if (sysAdmin.getAdminId().equals(adminId))  //该电话为他本人拥有
            return ResultVO.success(true);
        return ResultVO.success(false);
    }

    /**
     * 查询管理员列表
     *
     * @param page  页数
     * @param size  每页大小
     * @param isAsc 是否正序排序
     * @param field 排序的字段
     * @return ResultVO
     */
    @GetMapping
    public ResultVO findList(@RequestParam(name = "page", defaultValue = "1") Integer page,
                             @RequestParam(name = "size", defaultValue = "10") Integer size,
                             @RequestParam(name = "isAsc", defaultValue = "true") Boolean isAsc,
                             @RequestParam(name = "field", defaultValue = "adminId") String field) {
        //排序
        Sort sort = SortUtils.getSort(isAsc, field);
        PageRequest pageRequest = PageRequest.of(page - 1, size, sort);
        Page<SysAdmin> admins = sysAdminService.queryAllPage(pageRequest);
        return ResultVO.success(admins);
    }

    /**
     * 查询所有
     */
    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @GetMapping("/all")
    public ResultVO findAll() {
        return ResultVO.success(sysAdminService.queryAll());
    }

    /**
     * 查询该账号拥有所有角色
     */
    @GetMapping("/roleIds")
    public ResultVO findAllRoleIds(@RequestParam(name = "adminId") Long adminId) {
        return ResultVO.success(userRoleService.findRoleIdByAdminId(adminId));
    }

    /**
     * 条件查询管理员列表
     *
     * @param page  页数
     * @param size  每页大小
     * @param isAsc 是否正序排序
     * @param field 排序的字段
     * @return ResultVO
     */
    @GetMapping("/search")
    public ResultVO searchList(@RequestParam(name = "name", defaultValue = "") String name,
                               @RequestParam(name = "phone", defaultValue = "") String phone,
                               @RequestParam(name = "status", required = false)  Integer status,
                               @RequestParam(name = "dates", required = false) Date[] dates,
                               @RequestParam(name = "page", defaultValue = "1") Integer page,
                               @RequestParam(name = "size", defaultValue = "10") Integer size,
                               @RequestParam(name = "isAsc", defaultValue = "true") Boolean isAsc,
                               @RequestParam(name = "field", defaultValue = "") String field) {
        PageRequest pageRequest = null;
        if (StringUtils.isEmpty(field)) {
            pageRequest = PageRequest.of(page - 1, size);
        } else {
            //排序
            Sort sort = SortUtils.getSort(isAsc, field);
            pageRequest = PageRequest.of(page - 1, size, sort);
        }
        if (dates==null || dates.length<2){
            dates = new Date[2];
        }

        Page<SysAdmin> admins = sysAdminService.searchList(name, phone, status, dates, pageRequest);
        return ResultVO.success(admins);
    }

    /**
     *  保存 管理员
     *
     * @param adminForm 管理员对象
     * @return ResultVO
     */
    @PostMapping
    @Transactional
    public ResultVO saveSysAdmin(@RequestBody SysAdminForm adminForm) {
        SysAdmin admin = new SysAdmin();
        BeanUtils.copyProperties(adminForm,admin);
        SysAdmin newAdmin = sysAdminService.insert(admin);
        for (Long roleId : adminForm.getRoles()) {
            SysUserRole userRole = new SysUserRole();
            userRole.setAdminId(newAdmin.getAdminId());
            userRole.setRoleId(roleId);
            userRoleService.insert(userRole);
        }
        return ResultVO.success(newAdmin);
    }

    /**
     * 更新 管理员
     *
     * @param adminForm 管理员对象
     * @return ResultVO
     */
    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @PutMapping
    @Transactional
    public ResultVO updateSysAdmin(@RequestBody SysAdminForm adminForm) {
        SysAdmin admin = new SysAdmin();
        BeanUtils.copyProperties(adminForm,admin);
        if (adminForm.getRoles() != null)
            userRoleService.updateRoleByAdminId(adminForm.getRoles(),adminForm.getAdminId());
        return ResultVO.success(sysAdminService.update(admin));
    }

    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @PutMapping("/bind/openid")
    public ResultVO bindOpenid(@RequestParam(name = "adminId") Long adminId, @RequestParam(name = "code") String code) throws JsonProcessingException {

        String openid = WeiXinUtils.getRealOpenid(code, inspectorsProperties.getAppId(), inspectorsProperties.getAppSecret());
        SysAdmin adminOrigin = sysAdminService.findByOpenid(openid);
        //解绑原来的账号
        if (adminOrigin != null) {
            adminOrigin.setOpenid("");
            sysAdminService.update(adminOrigin);
        }
        //更新
        SysAdmin admin = new SysAdmin();
        admin.setAdminId(adminId);
        admin.setOpenid(openid);
        sysAdminService.update(admin);


        return ResultVO.success("绑定当前账号成功！");
    }


    @DeleteMapping
    public ResultVO deleteSysAdmin(@RequestParam("id") Long id) {
        sysAdminService.deleteById(id);
        return ResultVO.success();
    }

    @DeleteMapping("/list")
    public ResultVO deleteSysAdminList(@RequestParam("ids") Long[] ids) {
        sysAdminService.deleteByAdminIdIn(ids);
        return ResultVO.success();
    }

    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @GetMapping("/password")
    public ResultVO getPassword(@RequestParam("id") Long id){
        String password = sysAdminService.getPassword(id);
        ResultVO resultVO = ResultVO.success();
        resultVO.put("password",password);
        return resultVO;
    }

    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @PostMapping("/password")
    public ResultVO setPassword(@RequestParam("id") Long id, @RequestParam("password") String password){
        sysAdminService.setPassword(id,password);
        return ResultVO.success();
    }

    /**
     * 修改密码
     * @param id
     * @param oldPassword
     * @param password
     * @return
     */
    @Secured({"ROLE_SUPER_ADMIN","ROLE_ADMIN","ROLE_CHECK_MAN"})
    @PostMapping("/password/update")
    public ResultVO setPassword(@RequestParam("id") Long id,
                                @RequestParam("oldPassword") String oldPassword,
                                @RequestParam("password") String password){
        String originPassword = sysAdminService.getPassword(id);
        if (originPassword!=null && oldPassword!=null && oldPassword.equals(originPassword)){
            sysAdminService.setPassword(id,password);
            return ResultVO.success();
        }

        return ResultVO.error("修改密码错误！或许原密码不正确");

    }
}
